package YAPclient;

//import YAPenvironment.YAPconstant;
import javax.swing.*;

import YAPenvironment.YAPconstant;
import YAPenvironment.YAPconstant.Command;
import YAPenvironment.YAPerrorCode;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.net.*;
import java.util.Properties;


/**
 * The main class of the game. This class will be started from the client.
 * @param args
 */
public class YAPgame extends JFrame implements ActionListener, MouseListener{


	private static final long serialVersionUID = -2346321002153984348L;
	
	private String sep = YAPconstant.C_SEPARATOR;
	static JTextField ipTF;
	static JTextField portTF;
	static JTextField nameTF;
	private JList lstServers;
	private static DefaultListModel serverModel = new DefaultListModel();
	private static DiscoveryClient discovery;

	public static void main(String[] args) {
		if(args.length>0)
			createClient(args[0]);
		else
			createClient(null);
	}
	
	public static void createClient(String args){
		
		if (DataModul.initialization()){
			new YAPgame();
			discovery = new DiscoveryClient();
			
			if(args!=null){
				try{
					if(ipTF!=null){
						ipTF.setText(args.split(":")[0]);
					}
					if(portTF!=null){
						int port  = Integer.parseInt(args.split(":")[1]);
						portTF.setText(port+"");
					}
				}catch (NumberFormatException e){
					if(portTF!=null)
						portTF.setText(YAPconstant.C_PORT+"");
				}catch (Exception e){
					
				}
			}
		}
	}
	
	/**
	 * The consturctor which creates the connect-to-a-Server-GUI for the client.
	 */
	public YAPgame(){
		
		try {
	        // Set System L&F
	      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

		 } catch(Exception e){
			 if(YAPconstant.C_DEBUG){ e.printStackTrace(); }
		 }
		
		setTitle("Connect to server");
		setIconImage(YAPconstant.ICONIMAGE);
		
		setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		
		c.fill =GridBagConstraints.BOTH;
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 2;
		c.insets = new Insets(10,10,10,10);
		JLabel img=new JLabel();
		int width = this.getToolkit().getScreenSize().height/3;
		int height = width;
		Image scaledImage = (new ImageIcon(YAPconstant.imgURL)).getImage().getScaledInstance(width,height,java.awt.Image.SCALE_SMOOTH);
		img.setIcon(new ImageIcon(scaledImage));  
		add(img,c);
		
		JScrollPane jsp = new JScrollPane();
		jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		lstServers=new JList(getServerModel());
		lstServers.addMouseListener(this);
		lstServers.	setVisibleRowCount(2);
		jsp.setPreferredSize(new Dimension(width,lstServers.getPreferredSize().height));
		c.gridwidth =2 ;
		c.gridx = 0;
		c.gridy = 1;
		c.ipady = 57;
		jsp.setViewportView(lstServers);
		add(jsp,c);
		
		c.gridwidth = 1;
		c.ipady = 1;
		
		c.gridx = 0;
        c.gridy = 2;
		c.insets = new Insets(10,10,10,10);
		add(new JLabel("IP: "),c);
		
		ipTF=new JTextField("localhost");
		c.gridx=1;
		c.gridy=2;
		add(ipTF,c);

		c.gridx=0;
		c.gridy=3;
		c.insets = new Insets(10,10,10,10);
		add(new JLabel("PORT: "),c);
		
		portTF=new JTextField(""+YAPconstant.C_PORT);
		c.gridx=1;
		c.gridy=3;
		add(portTF,c);
		
		c.gridx=0;
		c.gridy=4;
		c.insets = new Insets(10,10,10,10);
		add(new JLabel("Name: "),c);
		
		nameTF=new JTextField(new Properties(System.getProperties()).getProperty("user.name"));
		//nameTF.setEnabled(false);
		c.gridx=1;
		c.gridy=4;
		add(nameTF,c);
		
		JButton connect = new JButton("connect");
		connect.addActionListener(this);
		c.gridx=0;
		c.gridy=5;
		c.gridwidth=2;
		add(connect,c);
       
		pack();
		setLocationRelativeTo(null);
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		connectToServer();
	}

	@Override
	public void mouseClicked(MouseEvent evt) {
		if(lstServers!=null && lstServers!=null && evt.getSource()==lstServers)
			try{
				ipTF.setText(lstServers.getSelectedValue().toString().split(":")[0]);
				portTF.setText(lstServers.getSelectedValue().toString().split(":")[1]);
			}catch (Exception e){
				//ignore
			}
		if (evt.getClickCount() == 2) {
			connectToServer();
		}
	}

	@Override
	public void mousePressed(MouseEvent e) {
	}
	@Override
	public void mouseReleased(MouseEvent e) {
		
	}
	@Override
	public void mouseEntered(MouseEvent e) {
	}
	@Override
	public void mouseExited(MouseEvent e) {
	}

	public static DefaultListModel getServerModel() {
		return serverModel;
	}
	
	private void connectToServer(){
		DataModul.clPlayer.setIP(ipTF.getText());
		DataModul.clPlayer.setPort(Integer.parseInt( portTF.getText()));
		DataModul.clPlayer.setName( nameTF.getText() );
		
		try {
			DataModul.sSocket = new Socket(DataModul.clPlayer.getIP(),DataModul.clPlayer.getPort());
			DataModul.parseThread.initialiceSocket(DataModul.sSocket);
			
			DataModul.parseThread.writeMessage(Command.connect.toString()+sep + DataModul.clPlayer.getName() + sep + DataModul.clPlayer.getUdpPort());
			String answer=DataModul.parseThread.readMessage();
			
			// Cut the last char off, if it is YAPconstant.cmdSeparator
			if (answer.charAt(answer.length()-1) == YAPconstant.C_CMD_SEPARATOR.toCharArray()[0]){
				answer = answer.substring(0, answer.length()-1);
			}

			int code=Integer.parseInt(answer.split(sep)[1]);
			if(answer.startsWith(Command.connect.toString()+sep+"0")){
				
				String name=answer.split(sep)[2];
				
				/**
				 * TODO:
				 * test after dinner:
				 */
				DataModul.hostAddress = DataModul.sSocket.getInetAddress();
				//DataModul.hostAddress = InetAddress.getByName(  DataModul.sSocket.getInetAddress().getHostAddress()  );
				
				System.out.println("***CONNECTED***");
				//now Connected, open the new Window with LobbyList etc!
				DataModul.clPlayer.setName(name);
				DataModul.running = true;
				DataModul.isAliveThread.setTimeSent(System.currentTimeMillis());
				DataModul.flo =new FormLobbyOverview();
				dispose();
				if(discovery!=null){
					discovery.close();
					discovery=null;
				}
				//setVisible(false); besser?
			}else{
				nameTF.setText(YAPerrorCode.getErrorMsg(code));
				DataModul.sSocket.close();
				DataModul.sSocket = null;
			}
		} catch (BindException exc){
			nameTF.setText("Port is already in use");
		} catch (IllegalArgumentException exc){
			nameTF.setText("Port outside of range: 0 to 65535");
		} catch (SecurityException exc){
			nameTF.setText("There has been a security exception");
		}catch(UnknownHostException exc){
			nameTF.setText("Couldn't find host");
		}catch (IOException exc ){
			nameTF.setText("Couldn't initialize Socket");
		} catch (Exception exc) {
			if(YAPconstant.C_DEBUG){ exc.printStackTrace(); }
			nameTF.setText("Connection couldn't be established");
		}
	}
}
